package cn.iocoder.yudao.module.wms.service.checkvouch;

import cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils;
import cn.iocoder.yudao.module.bpm.api.task.BpmProcessInstanceApi;
import cn.iocoder.yudao.module.bpm.api.task.dto.BpmProcessInstanceCreateReqDTO;
import cn.iocoder.yudao.module.bpm.enums.task.BpmTaskStatusEnum;
import cn.iocoder.yudao.module.wms.dal.dataobject.pomain.PomainDO;
import cn.iocoder.yudao.module.wms.dal.redis.RedisKeyConstants;
import cn.iocoder.yudao.module.wms.dal.redis.serialNumber.WmsSerialNumberRedisDAO;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
import org.springframework.validation.annotation.Validated;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;
import cn.iocoder.yudao.module.wms.controller.admin.checkvouch.vo.*;
import cn.iocoder.yudao.module.wms.dal.dataobject.checkvouch.CheckvouchDO;
import cn.iocoder.yudao.module.wms.dal.dataobject.checkvouch.CheckvouchsDO;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.framework.common.pojo.PageParam;
import cn.iocoder.yudao.framework.common.util.object.BeanUtils;

import cn.iocoder.yudao.module.wms.dal.mysql.checkvouch.CheckvouchMapper;
import cn.iocoder.yudao.module.wms.dal.mysql.checkvouch.CheckvouchsMapper;

import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
import static cn.iocoder.yudao.module.wms.enums.ErrorCodeConstants.*;

/**
 * 盘点 Service 实现类
 *
 * @author 芋道源码
 */
@Service
@Validated
public class CheckvouchServiceImpl implements CheckvouchService {
    /**
     * OA 对应的流程定义 KEY
     */
    public static final String PROCESS_KEY = "checkvouch";

    @Resource
    private CheckvouchMapper checkvouchMapper;
    @Resource
    private CheckvouchsMapper checkvouchsMapper;
    @Resource
    private WmsSerialNumberRedisDAO serialNumberRedisDAO;
    @Resource
    private BpmProcessInstanceApi processInstanceApi;
    @Override
    @Transactional(rollbackFor = Exception.class)
    public Integer createCheckvouch(CheckvouchSaveReqVO createReqVO) {
        String serialNumber = serialNumberRedisDAO.generate(WmsSerialNumberRedisDAO.POMAIN_SERIAL_PREFIX, RedisKeyConstants.SERIALPO);

        // 插入
        CheckvouchDO checkvouch = BeanUtils.toBean(createReqVO, CheckvouchDO.class)
                .setCode(serialNumber) .setStatus(BpmTaskStatusEnum.SUBMIT.getStatus());
        checkvouchMapper.insert(checkvouch);

        // 插入子表
        createCheckvouchsList(checkvouch.getId(), createReqVO.getCheckvouchss());
        // 返回
        return checkvouch.getId();
    }

    @Override
    public void process(Integer id)
    {
        /***
         * 启动流程
         */

        // 发起 BPM 流程
        Map<String, Object> processInstanceVariables = new HashMap<>();
        String processInstanceId = processInstanceApi.createProcessInstance(SecurityFrameworkUtils.getLoginUserId(),
                new BpmProcessInstanceCreateReqDTO().setProcessDefinitionKey(PROCESS_KEY)
                        .setVariables(processInstanceVariables).setBusinessKey(String.valueOf(id)));

        // 将工作流的编号，更新到 业务表单中
        checkvouchMapper.updateById(new CheckvouchDO().setId(id).setProcessInstanceId(processInstanceId).setStatus(BpmTaskStatusEnum.RUNNING.getStatus()));
        //将链接加入到ACT_HI_PROCINST表中
//        actHiProcinstMapper.updateURLById("/order/pomainForm?id="+pomainId,processInstanceId);
    }

    @Override
    public void updateStatus(CheckvouchSaveReqVO checkvouchSaveReqVO) {
        checkvouchMapper.updateStatus(checkvouchSaveReqVO);
    }

    @Override
    public CheckvouchDO findByProcessInstanceId(String processInstanceId) {
        return checkvouchMapper.findByProcessInstanceId(processInstanceId);
    }


    @Override
    @Transactional(rollbackFor = Exception.class)
    public void updateCheckvouch(CheckvouchSaveReqVO updateReqVO) {
        // 校验存在
        validateCheckvouchExists(updateReqVO.getId());
        // 更新
        CheckvouchDO updateObj = BeanUtils.toBean(updateReqVO, CheckvouchDO.class);
        checkvouchMapper.updateById(updateObj);

        // 更新子表
        updateCheckvouchsList(updateReqVO.getId(), updateReqVO.getCheckvouchss());
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void deleteCheckvouch(Integer id) {
        // 校验存在
        validateCheckvouchExists(id);
        // 删除
        checkvouchMapper.deleteById(id);

        // 删除子表
        deleteCheckvouchsByPid(id);
    }

    private void validateCheckvouchExists(Integer id) {
        if (checkvouchMapper.selectById(id) == null) {
            throw exception(CHECKVOUCH_NOT_EXISTS);
        }
    }

    @Override
    public CheckvouchDO getCheckvouch(Integer id) {
        return checkvouchMapper.selectById(id);
    }

    @Override
    public PageResult<CheckvouchDO> getCheckvouchPage(CheckvouchPageReqVO pageReqVO) {
        return checkvouchMapper.selectPage(pageReqVO);
    }

    // ==================== 子表（盘点子） ====================

    @Override
    public List<CheckvouchsDO> getCheckvouchsListByPid(Integer pid) {
        return checkvouchsMapper.selectListByPid(pid);
    }

    @Override
    public CheckvouchsRespVO findCheckvouchsById(Integer id) {
        return checkvouchMapper.findCheckvouchsById(id);
    }

    private void createCheckvouchsList(Integer pid, List<CheckvouchsDO> list) {
        list.forEach(o -> o.setPid(pid));
        checkvouchsMapper.insertBatch(list);
    }

    private void updateCheckvouchsList(Integer pid, List<CheckvouchsDO> list) {
        deleteCheckvouchsByPid(pid);
		list.forEach(o -> o.setId(null).setUpdater(null).setUpdateTime(null)); // 解决更新情况下：1）id 冲突；2）updateTime 不更新
        createCheckvouchsList(pid, list);
    }

    private void deleteCheckvouchsByPid(Integer pid) {
        checkvouchsMapper.deleteByPid(pid);
    }

}